#include "win_utils.h"
#include "objectmodel.h"
#include "mapdrawer.h"

#define ID_PAINT_FIELD 1100
#define ID_TOOL_BAR 1101


ATOM RegMyWindowClass(HINSTANCE hInst, LPCTSTR lpzClassName)
{
  WNDCLASS wcWindowClass = {0};
  wcWindowClass.lpfnWndProc = (WNDPROC)WndProc;
  wcWindowClass.lpszMenuName  = MAKEINTRESOURCE(IDR_MENU1);
 
  wcWindowClass.style = CS_HREDRAW|CS_VREDRAW;
  wcWindowClass.hInstance = hInst;
  wcWindowClass.lpszClassName = lpzClassName;
  wcWindowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
  wcWindowClass.hbrBackground = (HBRUSH)COLOR_APPWORKSPACE;
  return RegisterClass(&wcWindowClass); 
}

HWND DrawWindow(HWND parent)
{
	RECT rect;
	GetClientRect(parent, &rect);	

	WNDCLASS wcWindowClass = {0};
	wcWindowClass.lpfnWndProc = (WNDPROC)DRPROC;
	wcWindowClass.style = CS_HREDRAW|CS_VREDRAW;
	wcWindowClass.hInstance = GetModuleHandle(NULL);
	wcWindowClass.lpszClassName = "PaintField";
	wcWindowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
	wcWindowClass.hbrBackground = (HBRUSH)COLOR_APPWORKSPACE;
	RegisterClass(&wcWindowClass);

	return CreateWindowEx(0, "PaintField", NULL, 
		WS_BORDER | WS_CHILD | WS_VISIBLE, rect.left, rect.top + 20, (rect.right - rect.left), (rect.bottom - rect.top),
		parent, (HMENU) (int) (ID_PAINT_FIELD), GetModuleHandle(NULL), NULL);
}

HWND CreateSimpleToolbar(HWND hWndParent)
{
	const int ImageListID = 0;
	const int numButtons = 3;
	const DWORD buttonStyles = BTNS_AUTOSIZE;
	const int bitmapSize = 16;
	
	RECT rect;
	GetClientRect(hWndParent, &rect);

	HWND hWndToolbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, 
		WS_CHILD | TBSTYLE_FLAT,
		rect.left, rect.bottom, rect.right - rect.left, bitmapSize + 2,
		hWndParent, (HMENU) (int) (ID_TOOL_BAR), GetModuleHandle(NULL), NULL);
	
	if (hWndToolbar == NULL)
	{
		return NULL;
	}

	HIMAGELIST g_hImageList = ImageList_Create(
		bitmapSize, bitmapSize,   
		ILC_COLOR16 | ILC_MASK,   
		numButtons, 0);

	SendMessage(hWndToolbar, TB_SETIMAGELIST, (WPARAM)ImageListID, 
		(LPARAM)g_hImageList);

	SendMessage(hWndToolbar, TB_LOADIMAGES, (WPARAM)IDB_STD_SMALL_COLOR, 
		(LPARAM)HINST_COMMCTRL);

	TBBUTTON tbButtons[numButtons] = 
	{
		{ MAKELONG(STD_FILENEW, ImageListID), ID_FILE_NEW, TBSTATE_ENABLED, 
		buttonStyles,{0}, 0, NULL },
		{ MAKELONG(STD_FILEOPEN, ImageListID), ID_FILE_LOAD, TBSTATE_ENABLED, 
		buttonStyles, {0}, 0, NULL},
		{ MAKELONG(STD_FILESAVE, ImageListID), ID_FILE_SAVE40016, TBSTATE_ENABLED, 
		buttonStyles, {0}, 0, NULL}
	};

	SendMessage(hWndToolbar, TB_BUTTONSTRUCTSIZE, 
		(WPARAM)sizeof(TBBUTTON), 0);
	SendMessage(hWndToolbar, TB_ADDBUTTONS, (WPARAM)numButtons, 
		(LPARAM)&tbButtons);

	SendMessage(hWndToolbar, TB_AUTOSIZE, 0, 0); 
	ShowWindow(hWndToolbar, TRUE);
	return hWndToolbar;
}

MapDrawer newgr;

LRESULT CALLBACK WndProc(
	HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	//static MapDrawer newgr;

	switch (message)
	{
	case WM_CREATE:
		{
			HWND drwnd = DrawWindow(hWnd);
			GetMenu(hWnd);
			newgr.setHWND(drwnd);
			CreateSimpleToolbar(hWnd);
			break;
		}
	case WM_SIZE:
		{
			RECT rect;
			GetClientRect(hWnd, &rect);
			EnumChildWindows(hWnd, EnumChildProc, (LPARAM) &rect);
			break;
		}
	case WM_COMMAND:
		{
			switch (LOWORD(wParam)) 
			{
			case ID_FILE_NEW:
				{
					break;
				}
			case ID_FILE_LOAD:
				{
					DBMaster data;
					CallFileDialog(data, OFN_PATHMUSTEXIST, hWnd);
					newgr.setData(data);
					newgr.redraw();
					break;		  
				}
			case ID_FILE_SAVE40016:
				{
					CallFileDialog(newgr.getData(), OFN_OVERWRITEPROMPT, hWnd);
					break;	
				}
			case ID_FILE_EXIT:
				{
					PostQuitMessage(0);
					break;
				}
			case ID_PROP:
				{
					DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_EDITOR), hWnd, EDPROC);
					break;
				}
			}
			break;
		}
	case WM_PAINT:
		{
			PAINTSTRUCT ps;
			BeginPaint(hWnd,&ps);
			EndPaint(hWnd,&ps);
			
			BeginPaint(newgr.getHWND(), &ps);
			newgr.redraw();
			EndPaint(newgr.getHWND(), &ps);				
			
			break; 
		}
	case WM_KEYDOWN:
		{
			switch(wParam)
			{
			case VK_OEM_MINUS:
				newgr.zoomOut();
				break;
			case VK_OEM_PLUS:
				newgr.zoomIn();
				break;
			case VK_LEFT:
				newgr.moveLeft();
				break;
			case VK_RIGHT:
				newgr.moveRight();
				break;
			case VK_UP:
				newgr.moveTop();
				break;
			case VK_DOWN:
				newgr.moveBottom();
				break;
			}
			return 0;
		}
	case WM_DESTROY:
		{
			PostQuitMessage(0);  
			break;
		}
	default:  
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}

BOOL CALLBACK EDPROC(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	static HWND hStatic1;
	switch (uMsg) 
	{
		case WM_INITDIALOG:
			return TRUE;
		case WM_COMMAND:
			{
				switch (LOWORD(wParam)) 
				{
					case IDOK:
					case IDCANCEL:
						EndDialog(hDlg, 0);
						return TRUE;
				}
				break;
			}
	}
	return FALSE;
}

BOOL CALLBACK DRPROC(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg)
	{
		case  WM_CREATE:
			{
				break;
			}
		case  WM_PAINT:
			{
				break;
			}
		case WM_MOUSEMOVE:
			{
				if(!newgr.empty())
				{
					POINT point;
					point.x = GET_X_LPARAM(lParam); 
					point.y = GET_Y_LPARAM(lParam);
					newgr.getTip(point);
				}
				break;
			}
	}
	return TRUE;
}

BOOL CALLBACK EnumChildProc(HWND hwndChild, LPARAM lParam)
{
	LPRECT rect = (LPRECT) lParam;
	int id = GetWindowLong(hwndChild, GWL_ID);
	if (id == ID_PAINT_FIELD)
		MoveWindow(hwndChild, rect->left, rect->top + 24, 
						(rect->right - rect->left), (rect->bottom - rect->top), TRUE);
	else if (id == ID_TOOL_BAR)
		MoveWindow(hwndChild, rect->left, rect->top, 
						(rect->right - rect->left), 18, TRUE);
	ShowWindow(hwndChild, SW_SHOW);
	return TRUE;
}

void CallFileDialog(DBMaster & data, DWORD flag, HWND hWnd)
{
	OPENFILENAME ofn;
	char szFile[260];
	ZeroMemory(&ofn, sizeof(ofn));
	ofn.lStructSize = sizeof(ofn);
	ofn.hwndOwner = hWnd;
	ofn.lpstrFile = szFile;
	ofn.lpstrFile[0] = '\0';
	ofn.nMaxFile = sizeof(szFile);
	ofn.lpstrFilter = "XML\0*.XML\0Text\0*.TXT\0";
	ofn.nFilterIndex = 1;
	ofn.lpstrFileTitle = NULL;
	ofn.nMaxFileTitle = 0;
	ofn.lpstrInitialDir = NULL;
	ofn.Flags = flag;

	if (GetOpenFileName(&ofn) == TRUE) 
	{
		int src = data.OpenMode(ofn.lpstrFile);
		if (src == -1) 
		{ 
			MessageBox(hWnd, "file format is not supported", "Error", MB_OK);
		}
		else
		{
			if(flag == OFN_PATHMUSTEXIST)
				data.ReadData(ofn.lpstrFile, src);
			else if(flag == OFN_OVERWRITEPROMPT)
				data.WriteData(ofn.lpstrFile, src);
		}
	}
}